import { XY } from "../coord/XY";
import { Precision } from "../Precision";
import { Vector2 } from "../vector/Vector2";

/**
 * @description 二维空间坐标点
 * @author xuld
 * @date 2024-11-08
 * @lastEditTime 2024-11-08 17:59:53
 * @lastEditors xuld
 */
export class Point2 {
    private _coord: XY;

    /**
     * @description 创建二维点
     * @param x - X坐标值，默认为0
     * @param y - Y坐标值，默认为0
     */
    constructor(x: number = 0, y: number = 0) {
        this._coord = new XY(x, y);
    }

    /**
     * @description 获取X坐标值
     */
    public get x(): number {
        return this._coord.x;
    }

    /**
     * @description 设置X坐标值
     */
    public set x(value: number) {
        this._coord.x = value;
    }

    /**
     * @description 获取Y坐标值
     */
    public get y(): number {
        return this._coord.y;
    }

    /**
     * @description 设置Y坐标值
     */
    public set y(value: number) {
        this._coord.y = value;
    }

    /**
     * @description 获取内部坐标对象
     */
    public get coord(): XY {
        return this._coord;
    }

    /**
     * @description 设置内部坐标对象
     */
    public set coord(value: XY) {
        this._coord = value;
    }

    /**
     * @description 根据向量移动到新的点位，返回新的结果对象
     * @param vec - 位移向量
     * @returns 新的点对象
     */
    public moveBy(vec: Vector2): Point2 {
        let ret = this.clone();
        ret.moveSelfBy(vec);
        return ret;
    }

    /**
     * @description 根据向量移动到新的点位，直接修改自身的值
     * @param vec - 位移向量
     */
    public moveSelfBy(vec: Vector2): void {
        this.coord.addSelf(vec.coord);
    }

    /**
     * @description 计算两点之间的距离
     * @param other - 另一个点
     * @returns 距离值
     */
    public distance(other: Point2): number {
        return this._coord.distanceTo(other._coord);
    }

    /**
     * @description 判断两点是否相等
     * @param other - 要比较的点
     * @param tolerance - 容差值，默认为 EPSILON4
     * @returns 是否相等
     */
    public equals(other: Point2, tolerance: number = Precision.EPSILON4): boolean {
        return this._coord.equals(other._coord, tolerance);
    }

    /**
     * @description 从其他点复制坐标值
     * @param other - 要复制的点
     */
    public copyFrom(other: Point2): void {
        this._coord.copyFrom(other._coord);
    }

    /**
     * @description 计算从当前点到目标点的向量
     * @param pt - 目标点
     * @returns 方向向量
     */
    public vectorTo(pt: Point2): Vector2 {
        let vec = new Vector2(pt.x - this._coord.x, pt.y - this._coord.y);
        return vec;
    }

    /**
     * @description 创建当前点的副本
     * @returns 新的点对象
     */
    public clone(): Point2 {
        return new Point2(this.x, this.y);
    }

    /**
     * @description 点绕中心点旋转，返回新的点
     * @param radian - 旋转弧度
     * @param center - 旋转中心点，默认为原点(0,0)
     * @returns 旋转后的新点
     */
    public rotate(radian: number, center?: Point2): Point2 {
        let newPoint = this.clone();
        newPoint.coord.rotateSelf(radian, center?.coord);
        return newPoint;
    }

    /**
     * @description 点自身绕中心点旋转
     * @param radian - 旋转弧度
     * @param center - 旋转中心点，默认为原点(0,0)
     */
    public rotateSelf(radian: number, center?: Point2): void {
        this.coord.rotateSelf(radian, center?.coord);
    }

    /**
     * @description 转换为字符串表示
     * @returns 格式化的点字符串
     */
    public toString(): string {
        return `{"type": "Point2", "coord": ${this._coord.toString()}}`;
    }
}